package com.qf.ithub.movie_demo01.common.aop;

import com.qf.ithub.common.exception.AppException;
import com.qf.ithub.common.result.ResponseEnum;
import com.qf.ithub.movie_demo01.common.config.JWTConfig;
import com.qf.ithub.movie_demo01.entity.dto.LoginDTO;
import com.qf.ithub.movie_demo01.service.impl.RrightServiceImpl;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.List;

/**
 * @author : xixi
 * @Title :
 * @date :  2021-03-18 21:06
 */
@Component
@Aspect
public class AuthAspect {
    @Autowired
    private JWTConfig jwtConfig;
    @Autowired
    private RrightServiceImpl rightService;

    @Around("@annotation(com.qf.ithub.movie_demo01.common.aop.CheckLogin)")
    public Object beforeCheck(ProceedingJoinPoint joinPoint) throws Throwable {

        //1 从请求头中获得 token  request
        ServletRequestAttributes requestAttributes =
                (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();

        String token = request.getHeader("X-Token");
        LoginDTO loginDTO = jwtConfig.checkJwt(token);

        Integer roleid = loginDTO.getRoleid();
        Integer userid = loginDTO.getId();
        request.setAttribute("roleid",roleid);
        request.setAttribute("id",userid);

        // 1 判断是否为空
        if (StringUtils.isEmpty(token)) {
            throw new AppException(ResponseEnum.HAS_NO_TOKEN);
        }



        // 执行本体
        return joinPoint.proceed();

    }

    /*
    *动作权限得验证
    *
    * */
    @Around("@annotation(com.qf.ithub.movie_demo01.common.aop.CheckRight)")
    public Object beforeCheckRight(ProceedingJoinPoint joinPoint) throws Throwable {
        //  获得当前登录的用户的角色
        //1 从请求头中获得 token  request
        ServletRequestAttributes requestAttributes =
                (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();

        String token = request.getHeader("X-Token");
        // 1 判断是否为空
        if (StringUtils.isEmpty(token)) {
            throw new AppException(ResponseEnum.HAS_NO_TOKEN);
        }

        LoginDTO loginDTO = jwtConfig.checkJwt(token);
        Integer roleid = loginDTO.getRoleid();
        //  根据角色来获得 这个角色拥有的权限码的集合  [    ]
        List<String> rightcodes = rightService.getActionCodesByRoleid(roleid);
        // 通过反射获得 进入的方法 必须拥有的权限码 字符串
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        CheckRight checkRight = method.getDeclaredAnnotation(CheckRight.class);
        // 要执行这个方法需要的权限码
        String rightcode = checkRight.value();
        // 字符串是否在集合当中
        if(rightcodes.contains(rightcode)==false){
            //  如果没有该权限.. 抛出异常
            throw new AppException(ResponseEnum.HAS_NO_RIGHT);
        }

        //  如果又放行
        return joinPoint.proceed();
    }

}
